table of contents
CHOWN(2) | Руководство программиста Linux | CHOWN(2) |
ИМЯ¶
chown, fchown, lchown - изменить владельца файла
ОБЗОР¶
#include <unistd.h>
int chown(const char *path, uid_t
owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t
group);
int lchown(const char *path, uid_t owner, gid_t
group);
Требования
макроса
тестирования
свойств
для glibc (см.
feature_test_macros(7)):
fchown(), lchown():
|| /* начиная с glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
ОПИСАНИЕ¶
Данные системные вызовы изменяют владельца и группу для файла. Разница только в том, каким образом задается файл:
- chown() изменяет владельца для файла, задаваемого параметром path, который разыменовывается, если является символьной ссылкой.
- fchown() изменяет владельца для файла, задаваемого открытым файловым дескриптором fd.
- lchown() похож на chown() за исключением того, что он не разыменовывает символьные ссылки.
Только привилегированный процесс (Linux: имеющий мандат CAP_CHOWN) может сменить владельца файла. Владелец файла может сменить группу файла на любую группу, в которой он числится. Привилегированный процесс (Linux: с CAP_CHOWN) может задавать произвольную группу.
Если параметр owner или group равен -1, то соответствующий идентификатор не изменяется.
Когда владелец или группа исполняемого файла изменяется непривилегированным пользователем, то биты режима S_ISUID и S_ISGID сбрасываются. В POSIX не указано, должно ли это происходить если chown() выполняется суперпользователем; поведение в Linux зависит от версии ядра. В случае исполняемого файла вне группы (т.е., у которого не установлен бит S_IXGRP) бит S_ISGID указывает на обязательную блокировку, и не сбрасывается при выполнении chown().
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ¶
При успешном выполнении возвращается 0. В случае ошибки возвращается -1, а errno устанавливается в соответствующее значение.
ОШИБКИ¶
В зависимости от файловой системы могут также возвращаться другие ошибки. Общий набор ошибок chown() перечислен ниже:
- EACCES
- Поиск запрещён из-за одного из частей префикса пути (См. также path_resolution(7).)
- EFAULT
- Аргумент path указывает за пределы доступного адресного пространства.
- ELOOP
- Во время определения path встретилось слишком много символьных ссылок.
- ENAMETOOLONG
- path слишком длинен.
- ENOENT
- Файл не существует.
- ENOMEM
- Недостаточное количество памяти ядра.
- ENOTDIR
- Компонент в префиксе пути не является каталогом.
- EPERM
- Вызывающий процесс не имеет требуемых прав (см. выше), чтобы изменять владельца и/или группу.
- EROFS
- Файл находится на файловой системе, смонтированной только для чтения.
Общие ошибки fchown() таковы:
СООТВЕТСТВИЕ СТАНДАРТАМ¶
4.4BSD, SVr4, POSIX.1-2001.
Версия из 4.4BSD может использоваться только суперпользователем (то есть, обычные пользователи не могут менять владельцев).
ЗАМЕЧАНИЯ¶
Первоначальные версии системных вызовов chown(), fchown() и lchown() в Linux поддерживали только 16-битные идентификаторы пользователей и групп. Позднее в Linux 2.4 были добавлены вызовы chown32(), fchown32() и lchown32(), поддерживающие 32-битные идентификаторы. В glibc обёрточные функции chown(), fchown() и lchown() работают одинаково вне зависимости от версий ядра.
При создании нового файла (например с помощью open(2) или mkdir(2)), его владельцем будет установлен ID пользователя из файловой системы создающего процесса. Группа файла зависит от нескольких факторов, включая тип файловой системы, параметры монтирования и установлен ли бит set-group-ID на родительском каталоге. Если файловая система поддерживает параметры mount(8) -o grpid (тоже что и -o bsdgroups) и -o nogrpid (тоже что и -o sysvgroups), то правила следующие:
- Если файловая система смонтирована с параметром -o grpid, то группой нового файла будет группа родительского каталога.
- Если файловая система смонтирована с параметром -o nogrpid и на родительском каталоге сброшен бит set-group-ID, то группой нового файла будет GID файловой системы того же процесса.
- Если файловая система смонтирована с параметром -o nogrpid и на родительском каталоге установлен бит set-group-ID, то группой нового файла будет группа родительского каталога.
Начиная с Linux 2.6.25, параметры монтирования -o grpid и -o nogrpid поддерживаются для ext2, ext3, ext4 и XFS. Для файловых систем, не поддерживающих эти параметры монтирования, используются правила как для -o nogrpid.
Семантика chown() сознательно нарушается в файловых системах NFS, в которых включено отображение UID. Также, нарушается семантика всех системных вызовов, которые обеспечивают доступ к содержимому файлов, так как chown() может привести к немедленному отзыву доступа к уже открытым файлам. Кэширование на клиентской стороне может привести к задержке между сменой доступа пользователю и временем, когда файл действительно станет доступным.
В версиях Linux до 2.1.81 (кроме 2.1.46) chown() не следовал по символьным ссылкам. Начиная с версии Linux 2.1.81 chown() следует по символьным ссылкам, и существует новый системный вызов lchown(), который не следует по символьным ссылкам. Начиная с Linux 2.1.86 этот новый вызов (имеющий тот же смысл, что и старый chown()) имеет тот же самый номер системного вызова, а chown() получил новый номер.
ПРИМЕР¶
Следующая программа изменять владельца файла, указанного вторым в командной строке, на значение, указанное в первом аргументе командной строки. Новый владелец может задаваться в виде числового пользовательского ID, или в виде имени пользователя (которое преобразуется в пользовательский ID с помощью getpwnam(3), выполняющего поиск в системном файле паролей).
#include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) {
uid_t uid;
struct passwd *pwd;
char *endptr;
if (argc != 3 || argv[1][0] == '\0') {
fprintf(stderr, "%s <owner> <file>\n", argv[0]);
exit(EXIT_FAILURE);
}
uid = strtol(argv[1], &endptr, 10); /* Allow a numeric string */
if (*endptr != '\0') { /* Was not pure numeric string */
pwd = getpwnam(argv[1]); /* Try getting UID for username */
if (pwd == NULL) {
perror("getpwnam");
exit(EXIT_FAILURE);
}
uid = pwd->pw_uid;
}
if (chown(argv[2], uid, -1) == -1) {
perror("chown");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS); }
СМОТРИТЕ ТАКЖЕ¶
chmod(2), fchownat(2), flock(2), path_resolution(7), symlink(7)
2010-11-22 | Linux |